import { constantRoutes, notFound } from '@/router'
import Layout from '@/layout/index.vue'
import Share from '@/layout/Share.vue'
import Blank from '@/layout/Blank.vue'
import NoTop from '@/layout/NoTop.vue'
let dynamicViewsModules = null // 所有views下的组件

// 动态载入
function dynamicImport (dynamicViewsModules, component) {
  const keys = Object.keys(dynamicViewsModules)
  const matchKeys = keys.filter((key) => {
    let k = key.replace('../../views/', '')
    const lastIndex = k.lastIndexOf('.')
    k = k.substring(0, lastIndex)
    return k === component
  })
  if (matchKeys?.length === 1) {
    const matchKey = matchKeys[0]
    return dynamicViewsModules[matchKey]
  }
  if (matchKeys?.length > 1) {
    warn(
      '请不要在视图文件夹下的同一分层目录中使用相同的文件名创建“.vue`和`.tsx`文件。这将导致动态引入失败'
    );
    return
  }
}

// 挂在路由上的组件
export function mountRouter (asyncRouterMap) {
  const accessedRouters = asyncRouterMap.filter(route => {
    if (route.component) {
      if (route.component === 'Layout') { // 基础布局
        route.component = Layout
      } 
      else if (route.component === 'Blank') { // 空白页
        route.component = Blank
      } else if (route.component === 'Share') { // 外部链接页面
        route.component = Share
      } else if (route.component === 'NoTop') { // 空白页
        route.component = NoTop
      } else {
        // 关于import.meta.glob 可见：https://vitejs.dev/guide/features.html#json
        dynamicViewsModules = dynamicViewsModules || import.meta.glob('../../views/**/*.{vue,jsx,tsx}')
        route.component = dynamicImport(dynamicViewsModules, route.component)
      }
    }
    if (route.children && route.children.length) {
      route.children = mountRouter(route.children)
    }
    return true
  })
  return accessedRouters
}

// 将后端返回的路由数据转换为vue-router路由格式
function formatRoutes (routes = []) {
  return routes.map((item, index) => {
    const route = {
      id: item.id,
      path: item.path || '',
      name: item.code,
      redirect: item.redirect,
      component: item.uri,
      meta: {
        title: item.name,
        // rightMenu: item.code === 'system',
        icon: item.icon,
        keepAlive: item.keepAlive,
        activeMenu: item.activeMenu
      },
      hidden: item.hidden,
      children: item.children && formatRoutes(item.children)
    }
    for (const key in route) {
      if (!route[key] && route[key] !== '') {
        delete route[key]
      }
    }

    return route
  })
}

function getCacheList (routes = []) {
  const list = []
  function deepLoop (arr) {
    arr.forEach(item => {
      if (item.meta?.keepAlive) {
        list.push(item.name)
      }
      if (item.children?.length > 0) {
        deepLoop(item.children)
      }
    })
  }
  deepLoop(routes)

  return list
}

const state = {
  routes: [],
  addRoutes: [],
  cache: []
}

const mutations = {
  SET_ROUTES: (state, routes) => {
    state.addRoutes = routes
    state.routes = constantRoutes.concat(routes)
  },

  SET_CACHE: (state, list) => {
    state.cache = list
  },

  CLEAR_CACHE: (state) => {
    state.cache = []
  }
}

const actions = {
  generateRoutes ({ commit }, menus) {
    return new Promise((resolve, reject) => {
      const data = formatRoutes(menus)
      const accessedRoutes = mountRouter(data)
      // 最后再加入404页面，否则在载入过程中路由可能已经认为页面不存在了
      accessedRoutes.push(notFound)

      const cacheList = getCacheList(accessedRoutes)

      commit('SET_CACHE', cacheList)
      commit('SET_ROUTES', accessedRoutes)
      resolve(accessedRoutes)
    })
  }
}

export default {
  namespaced: true,
  state,
  mutations,
  actions
}
